package org.openit.portail.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.proxy.HibernateProxy;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;


/** 
 * Object mapping for hibernate-handled table: user_system.
 * @author autogenerated
 */

@Entity
@Table(name = "user_system", catalog = "portail")
public class UserSystem implements Cloneable, Serializable, UserDetails{

	/** Serial Version UID. */
	private static final long serialVersionUID = -559010011L;

	/** Use a WeakHashMap so entries will be garbage collected once all entities 
		referring to a saved hash are garbage collected themselves. */
	private static final Map<Serializable, Integer> SAVED_HASHES =
		Collections.synchronizedMap(new WeakHashMap<Serializable, Integer>());
	
	/** hashCode temporary storage. */
	private volatile Integer hashCode;
	/** Field mapping. */
	private String adresseIp;
	/** Field mapping. */
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
	private Date dateNaissance;
	/** Field mapping. */
	private Date dtCreation;
	/** Field mapping. */
	private Date dtModification;
	/** Field mapping. */
	private String email;
	/** Field mapping. */
	private Integer id = 0; // init for hibernate bug workaround
	/** Field mapping. */
	private UserSystem idCreationUser;
	/** Field mapping. */
	private UserSystem idModificationUser;
	/** Field mapping. */
	private Profil idProfil;
	/** Field mapping. */
	private String informationComplementaire;
	/** Field mapping. */
	private String masque;
	/** Field mapping. */
	private String motDePasse;
	/** Field mapping. */
	private String nom;
	/** Field mapping. */
	private String observation;
	/** Field mapping. */
	private String pays;
	/** Field mapping. */
	private String prenom;
    /** Field mapping. */
	private Integer telephone;
    /** Field mapping. */
	private String ville;
	/**
	 * Default constructor, mainly for hibernate use.
	 */
	public UserSystem() {
		// Default constructor
	} 

	/** Constructor taking a given ID.
	 * @param id to set
	 */
	public UserSystem(Integer id) {
		this.id = id;
	}
	
	/** Constructor taking a given ID.
	 * @param id Integer object;
	 * @param idProfil Profil object;
	 */
	public UserSystem(Integer id, Profil idProfil) {

		this.id = id;
		this.idProfil = idProfil;
	}
	
 


 
	/** Return the type of this class. Useful for when dealing with proxies.
	* @return Defining class.
	*/
	@Transient
	public Class<?> getClassType() {
		return UserSystem.class;
	}
    /**
     * Return the value associated with the column: adresseIp.
	 * @return A String object (this.adresseIp)
	 */
	@Column( name = "adresse_ip", length = 50  )
	public String getAdresseIp() {
		return this.adresseIp;
		
	}
	

  
    /**  
     * Set the value related to the column: adresseIp.
	 * @param adresseIp the adresseIp value you wish to set
	 */
	public void setAdresseIp(final String adresseIp) {
		this.adresseIp = adresseIp;
	}
	
    /**
     * Return the value associated with the column: dateNaissance.
	 * @return A Date object (this.dateNaissance)
	 */
	@Column( name = "date_naissance"  )
	public Date getDateNaissance() {
		return this.dateNaissance;
		
	}
	/**  
     * Set the value related to the column: dateNaissance.
	 * @param dateNaissance the dateNaissance value you wish to set
	 */
	public void setDateNaissance(final Date dateNaissance) {
		this.dateNaissance = dateNaissance;
	}

    /**
     * Return the value associated with the column: dtCreation.
	 * @return A Date object (this.dtCreation)
	 */
	@Column( name = "dt_creation"  )
	public Date getDtCreation() {
		return this.dtCreation;
		
	}
	/**  
     * Set the value related to the column: dtCreation.
	 * @param dtCreation the dtCreation value you wish to set
	 */
	public void setDtCreation(final Date dtCreation) {
		this.dtCreation = dtCreation;
	}

    /**
     * Return the value associated with the column: dtModification.
	 * @return A Date object (this.dtModification)
	 */
	@Column( name = "dt_modification"  )
	public Date getDtModification() {
		return this.dtModification;
		
	}
	

  
    /**  
     * Set the value related to the column: dtModification.
	 * @param dtModification the dtModification value you wish to set
	 */
	public void setDtModification(final Date dtModification) {
		this.dtModification = dtModification;
	}

    /**
     * Return the value associated with the column: email.
	 * @return A String object (this.email)
	 */
	@Column( length = 100  )
	public String getEmail() {
		return this.email;
		
	}
	

  
    /**  
     * Set the value related to the column: email.
	 * @param email the email value you wish to set
	 */
	public void setEmail(final String email) {
		this.email = email;
	}

    /**
     * Return the value associated with the column: id.
	 * @return A Integer object (this.id)
	 */
    @Id 
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column( name = "id_user", nullable = false  )
	public Integer getId() {
		return this.id;
		
	}
	

  
    /**  
     * Set the value related to the column: id.
	 * @param id the id value you wish to set
	 */
	public void setId(final Integer id) {
		// If we've just been persisted and hashCode has been
		// returned then make sure other entities with this
		// ID return the already returned hash code
		if ( (this.id == null || this.id == 0) &&
				(id != null) &&
				(this.hashCode != null) ) {
			SAVED_HASHES.put( id, this.hashCode );
		}
		this.id = id;
	}

    /**
     * Return the value associated with the column: idCreationUser.
	 * @return A UserSystem object (this.idCreationUser)
	 */
	@ManyToOne( cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY )
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	@JoinColumn(name = "Id_Creation_User", nullable = true )
	public UserSystem getIdCreationUser() {
		return this.idCreationUser;
		
	}
	

  
    /**  
     * Set the value related to the column: idCreationUser.
	 * @param idCreationUser the idCreationUser value you wish to set
	 */
	public void setIdCreationUser(final UserSystem idCreationUser) {
		this.idCreationUser = idCreationUser;
	}

    /**
     * Return the value associated with the column: idModificationUser.
	 * @return A UserSystem object (this.idModificationUser)
	 */
	@ManyToOne( cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY )
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	@JoinColumn(name = "Id_Modification_User", nullable = true )
	public UserSystem getIdModificationUser() {
		return this.idModificationUser;
		
	}
	

  
    /**  
     * Set the value related to the column: idModificationUser.
	 * @param idModificationUser the idModificationUser value you wish to set
	 */
	public void setIdModificationUser(final UserSystem idModificationUser) {
		this.idModificationUser = idModificationUser;
	}

    /**
     * Return the value associated with the column: idProfil.
	 * @return A Profil object (this.idProfil)
	 */
	@ManyToOne( cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER )
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	@JoinColumn(name = "Id_Profil", nullable = false )
	public Profil getIdProfil() {
		return this.idProfil;
		
	}
	

  
    /**  
     * Set the value related to the column: idProfil.
	 * @param idProfil the idProfil value you wish to set
	 */
	public void setIdProfil(final Profil idProfil) {
		this.idProfil = idProfil;
	}

    /**
     * Return the value associated with the column: informationComplementaire.
	 * @return A String object (this.informationComplementaire)
	 */
	@Column( name = "information_complementaire", length = 200  )
	public String getInformationComplementaire() {
		return this.informationComplementaire;
		
	}
	

  
    /**  
     * Set the value related to the column: informationComplementaire.
	 * @param informationComplementaire the informationComplementaire value you wish to set
	 */
	public void setInformationComplementaire(final String informationComplementaire) {
		this.informationComplementaire = informationComplementaire;
	}

    /**
     * Return the value associated with the column: masque.
	 * @return A String object (this.masque)
	 */
	@Column( length = 100  )
	public String getMasque() {
		return this.masque;
		
	}
	

  
    /**  
     * Set the value related to the column: masque.
	 * @param masque the masque value you wish to set
	 */
	public void setMasque(final String masque) {
		this.masque = masque;
	}
	/**
     * Return the value associated with the column: motDePasse.
	 * @return A String object (this.motDePasse)
	 */
	@Column( name = "mot_de_passe", length = 20  )
	public String getMotDePasse() {
		return this.motDePasse;
		
	}
	

  
    /**  
     * Set the value related to the column: motDePasse.
	 * @param motDePasse the motDePasse value you wish to set
	 */
	public void setMotDePasse(final String motDePasse) {
		this.motDePasse = motDePasse;
	}

    /**
     * Return the value associated with the column: nom.
	 * @return A String object (this.nom)
	 */
	@Column( length = 16777215  )
	public String getNom() {
		return this.nom;
		
	}
	

  
    /**  
     * Set the value related to the column: nom.
	 * @param nom the nom value you wish to set
	 */
	public void setNom(final String nom) {
		this.nom = nom;
	}

    /**
     * Return the value associated with the column: observation.
	 * @return A String object (this.observation)
	 */
	@Column( length = 16777215  )
	public String getObservation() {
		return this.observation;
		
	}
	

  
    /**  
     * Set the value related to the column: observation.
	 * @param observation the observation value you wish to set
	 */
	public void setObservation(final String observation) {
		this.observation = observation;
	}
    /**
     * Return the value associated with the column: pays.
	 * @return A String object (this.pays)
	 */
	@Column( length = 30  )
	public String getPays() {
		return this.pays;
		
	}
	/**  
     * Set the value related to the column: pays.
	 * @param pays the pays value you wish to set
	 */
	public void setPays(final String pays) {
		this.pays = pays;
	}

    /**
     * Return the value associated with the column: prenom.
	 * @return A String object (this.prenom)
	 */
	@Column( length = 16777215  )
	public String getPrenom() {
		return this.prenom;
		
	}
	

  
    /**  
     * Set the value related to the column: prenom.
	 * @param prenom the prenom value you wish to set
	 */
	public void setPrenom(final String prenom) {
		this.prenom = prenom;
	}
	/**
     * Return the value associated with the column: telephone.
	 * @return A Integer object (this.telephone)
	 */
	public Integer getTelephone() {
		return this.telephone;
		
	}
	/**  
     * Set the value related to the column: telephone.
	 * @param telephone the telephone value you wish to set
	 */
	public void setTelephone(final Integer telephone) {
		this.telephone = telephone;
	}
	 /**
     * Return the value associated with the column: ville.
	 * @return A String object (this.ville)
	 */
	@Column( length = 20  )
	public String getVille() {
		return this.ville;
		
	}
	

  
    /**  
     * Set the value related to the column: ville.
	 * @param ville the ville value you wish to set
	 */
	public void setVille(final String ville) {
		this.ville = ville;
	}


   /**
    * Deep copy.
	* @return cloned object
	* @throws CloneNotSupportedException on error
    */
    @Override
    public UserSystem clone() throws CloneNotSupportedException {
		
        final UserSystem copy = (UserSystem)super.clone();

		
		copy.setDateNaissance(this.getDateNaissance());
		copy.setDtCreation(this.getDtCreation());
		copy.setDtModification(this.getDtModification());
		copy.setEmail(this.getEmail());
		copy.setId(this.getId());
		copy.setIdCreationUser(this.getIdCreationUser());
		copy.setIdModificationUser(this.getIdModificationUser());
		copy.setIdProfil(this.getIdProfil());
		copy.setInformationComplementaire(this.getInformationComplementaire());
		copy.setMasque(this.getMasque());
		copy.setMotDePasse(this.getMotDePasse());
		copy.setNom(this.getNom());
		copy.setObservation(this.getObservation());
		copy.setPays(this.getPays());
		copy.setPrenom(this.getPrenom());
		copy.setTelephone(this.getTelephone());
		copy.setVille(this.getVille());
		return copy;
	}
	


	/** Provides toString implementation.
	 * @see java.lang.Object#toString()
	 * @return String representation of this class.
	 */
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		
		sb.append("adresseIp: " + this.getAdresseIp() + ", ");
		sb.append("dateNaissance: " + this.getDateNaissance() + ", ");
		sb.append("dtCreation: " + this.getDtCreation() + ", ");
		sb.append("dtModification: " + this.getDtModification() + ", ");
		sb.append("email: " + this.getEmail() + ", ");
		sb.append("id: " + this.getId() + ", ");
		sb.append("informationComplementaire: " + this.getInformationComplementaire() + ", ");
		sb.append("masque: " + this.getMasque() + ", ");
		sb.append("motDePasse: " + this.getMotDePasse() + ", ");
		sb.append("nom: " + this.getNom() + ", ");
		sb.append("observation: " + this.getObservation() + ", ");
		sb.append("pays: " + this.getPays() + ", ");
		sb.append("prenom: " + this.getPrenom() + ", ");
		sb.append("telephone: " + this.getTelephone() + ", ");
		sb.append("ville: " + this.getVille());
		return sb.toString();		
	}


	/** Equals implementation. 
	 * @see java.lang.Object#equals(java.lang.Object)
	 * @param aThat Object to compare with
	 * @return true/false
	 */
	@Override
	public boolean equals(final Object aThat) {
		Object proxyThat = aThat;
		
		if ( this == aThat ) {
			 return true;
		}

		
		if (aThat instanceof HibernateProxy) {
 			// narrow down the proxy to the class we are dealing with.
 			try {
				proxyThat = ((HibernateProxy) aThat).getHibernateLazyInitializer().getImplementation(); 
			} catch (org.hibernate.ObjectNotFoundException e) {
				return false;
		   	}
		}
		if (aThat == null)  {
			 return false;
		}
		
		final UserSystem that; 
		try {
			that = (UserSystem) proxyThat;
			if ( !(that.getClassType().equals(this.getClassType()))){
				return false;
			}
		} catch (org.hibernate.ObjectNotFoundException e) {
				return false;
		} catch (ClassCastException e) {
				return false;
		}
		
		
		boolean result = true;
		result = result && (((this.getId() == null) && ( that.getId() == null)) || (this.getId() != null  && this.getId().equals(that.getId())));
		result = result && (((getAdresseIp() == null) && (that.getAdresseIp() == null)) || (getAdresseIp() != null && getAdresseIp().equals(that.getAdresseIp())));
		result = result && (((getDateNaissance() == null) && (that.getDateNaissance() == null)) || (getDateNaissance() != null && getDateNaissance().equals(that.getDateNaissance())));
		result = result && (((getDtCreation() == null) && (that.getDtCreation() == null)) || (getDtCreation() != null && getDtCreation().equals(that.getDtCreation())));
		result = result && (((getDtModification() == null) && (that.getDtModification() == null)) || (getDtModification() != null && getDtModification().equals(that.getDtModification())));
		result = result && (((getEmail() == null) && (that.getEmail() == null)) || (getEmail() != null && getEmail().equals(that.getEmail())));
		result = result && (((getIdCreationUser() == null) && (that.getIdCreationUser() == null)) || (getIdCreationUser() != null && getIdCreationUser().getId().equals(that.getIdCreationUser().getId())));	
		result = result && (((getIdModificationUser() == null) && (that.getIdModificationUser() == null)) || (getIdModificationUser() != null && getIdModificationUser().getId().equals(that.getIdModificationUser().getId())));	
		result = result && (((getIdProfil() == null) && (that.getIdProfil() == null)) || (getIdProfil() != null && getIdProfil().getId().equals(that.getIdProfil().getId())));	
		result = result && (((getInformationComplementaire() == null) && (that.getInformationComplementaire() == null)) || (getInformationComplementaire() != null && getInformationComplementaire().equals(that.getInformationComplementaire())));
		result = result && (((getMasque() == null) && (that.getMasque() == null)) || (getMasque() != null && getMasque().equals(that.getMasque())));
		result = result && (((getMotDePasse() == null) && (that.getMotDePasse() == null)) || (getMotDePasse() != null && getMotDePasse().equals(that.getMotDePasse())));
		result = result && (((getNom() == null) && (that.getNom() == null)) || (getNom() != null && getNom().equals(that.getNom())));
		result = result && (((getObservation() == null) && (that.getObservation() == null)) || (getObservation() != null && getObservation().equals(that.getObservation())));
		result = result && (((getPays() == null) && (that.getPays() == null)) || (getPays() != null && getPays().equals(that.getPays())));
		result = result && (((getPrenom() == null) && (that.getPrenom() == null)) || (getPrenom() != null && getPrenom().equals(that.getPrenom())));
		result = result && (((getTelephone() == null) && (that.getTelephone() == null)) || (getTelephone() != null && getTelephone().equals(that.getTelephone())));
		result = result && (((getVille() == null) && (that.getVille() == null)) || (getVille() != null && getVille().equals(that.getVille())));
		return result;
	}
	
	/** Calculate the hashcode.
	 * @see java.lang.Object#hashCode()
	 * @return a calculated number
	 */
	@Override
	public int hashCode() {
		if ( this.hashCode == null ) {
			synchronized ( this ) {
				if ( this.hashCode == null ) {
					Integer newHashCode = null;

					if ( getId() != null ) {
						newHashCode = SAVED_HASHES.get( getId() );
					}
					
					if ( newHashCode == null ) {
						if ( getId() != null && getId() != 0) {
							newHashCode = getId();
						} else {
							newHashCode = super.hashCode();

						}
					}
					
					this.hashCode = newHashCode;
				}
			}
		}
	return this.hashCode;
	}



	@Transient
	public String getPassword() {
		return getMotDePasse();
	}

	@Transient
	public String getUsername() {
		return getEmail();
	}

	@Transient
	public boolean isAccountNonExpired() {
		return true;
	}

	@Transient
	public boolean isAccountNonLocked() {
		return true;
	}

	@Transient
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Transient
	public boolean isEnabled() {
		return true;
	}

	@Transient
	public Collection<GrantedAuthority> getAuthorities() {
		
			List<GrantedAuthority> userGaranties=new ArrayList<GrantedAuthority>();
			String profile=getIdProfil().getNom();
			GrantedAuthority adminAuthority = new GrantedAuthorityImpl(profile);
			userGaranties.add(adminAuthority);
			return userGaranties;
		
	}
	

	
}
